#region Disclaimer / License
// Copyright (C) 2008, Kenneth Skovhede
// http://www.hexad.dk, opensource@hexad.dk
// 
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
// 
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
// 
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
// 
#endregion
using System;
using System.Collections.Generic;

namespace System.Data.LightDatamodel
{
	/// <summary>
	/// All data providers must implement this interface
	/// </summary>
	public interface IDataProvider
	{
        void DeleteRow(object item);
        object SelectRow(Type type, object primarykey);
        object[] SelectRows(Type type, string filter);
        object[] SelectRows(Type type, QueryModel.Operation operation);
		void UpdateRow(object item);
		void InsertRow(object item);
		object Compute(string tablename, string expression, string filter);
		object GetLastAutogeneratedValue(string tablename);

		string GetPrimaryKey(string tablename);
        bool IsAutoIncrement(string tablename, string column);
		bool IsUnique(string tablename, string column);
		object GetDefaultValue(string tablename, string column);
		object GetDefaultValue(string tablename, string column, string sql);
		string[] GetTablenames();
        Dictionary<string, Type> GetStructure(string sql);
        Dictionary<string, Type> GetTableStructure(string tablename);
		object GetNullValue(Type type);
		int GetColumnStringLength(string tablename, string column);

		string ConnectionString { get;set;}
		IDbConnection Connection { get;set; }
		void BeginTransaction(Guid id);
		void CommitTransaction(Guid id);
		void RollbackTransaction(Guid id);
		void Close();
		IDataFetcher Parent { get; set;}
	}

	/// <summary>
	/// This should be thrown when an update/delete/create cen't fetch/find a given object
	/// </summary>
	[Serializable]
	public class NoSuchObjectException : Exception
	{
		private object m_object;
		public object Object { get{ return m_object;}}

		public NoSuchObjectException() { }
		public NoSuchObjectException(string message, object obj) : base(message)
		{
			m_object = obj;
		}
	}

	/// <summary>
	/// If a data provider supports assisted configuration, it must implement this interface.
	/// Must also have a default constructor.
	/// </summary>
	public interface IConfigureableDataProvider
	{
		/// <summary>
		/// This method should present a dialog for the user to configure the data provider.
		/// </summary>
		/// <param name="owner">The owner dialog</param>
		/// <param name="previousConnectionString">Any previously configured properties</param>
		/// <returns>The new connection properties, or null if the setup was cancelled</returns>
		ConfigureProperties Configure(System.Windows.Forms.Form owner, ConfigureProperties previousConnectionProperties);

		/// <summary>
		/// Returns a user identifiable name for the provider.
		/// </summary>
		string FriendlyName { get; }

		/// <summary>
		/// Return system name
		/// </summary>
		string Name { get; }

		/// <summary>
		/// This method should return a configuration for the provider, given the commandline arguments, or return null if the commandline was not meaningfull to the provider.
		/// </summary>
		/// <param name="arguments">The commandline arguments</param>
		/// <returns>A configuration for the provider, or null if the arguments where not meaningfull for the provider</returns>
		ConfigureProperties AutoConfigure(string[] arguments);

		/// <summary>
		/// Returns a dataprovider, given the connectionstring
		/// </summary>
		/// <param name="connectionstring"></param>
		/// <returns></returns>
		IDataProvider GetProvider(string connectionstring);
	}

	/// <summary>
	/// This class is used to transfer data to and from a configureable data provider
	/// </summary>
	public class ConfigureProperties
	{
		private string m_Connectionstring;
		private string m_DestinationDir;
		private string m_Namespace;
		public string Connectionstring { get { return m_Connectionstring; } set { m_Connectionstring = value; } }
		public string DestinationDir { get { return m_DestinationDir; } set { m_DestinationDir = value; } }
		public string Namespace { get { return m_Namespace; } set { m_Namespace = value; } }
	}
}
